package entities {
	import entities.Entity;
	
	import org.flixel.FlxG;
	import org.flixel.FlxObject;
	import org.flixel.FlxPoint;
	import org.flixel.FlxSprite;
	import org.flixel.FlxU;
	import org.flixel.plugin.photonstorm.FlxDelay;
	import org.flixel.plugin.photonstorm.FlxMath;
	
	import com.greensock.TweenMax;
	import com.greensock.easing.Linear;
	import com.greensock.easing.Sine;
	
	
	public class Enemy extends Entity {
		// options
		
		protected var _canCharge:Boolean;
		public var _tracking:Boolean;
		protected var _stayOnPlatform:Boolean;
		
		public function Enemy(X:int, Y:int, infos:Object) {
			super(X, Y, infos);
			
			_canCharge = infos.gamePlay.charging; // will randomly speedup ...
			_tracking = infos.gamePlay.tracking; // will follow the player position OR patrolling
			_stayOnPlatform = infos.gamePlay.stayOnPlatform; // will not jump off the platforms
			
			turnAround();
		
		}
		
		private var willFire:Boolean;
		private var fireTime:FlxDelay;
		protected var chargeDelay:FlxDelay;
		
		
		override public function update():void {
			super.update();
			
			if (onScreen() && !_isDying) {
				
				if (x < 0) x = 0;
				if (x > Registry.level.ground.width - width)
					x = Registry.level.ground.width - width;
				if (y > Registry.level.ground.height) super.kill();
				
				if (velocity.y == 0) {
					// shooting
					if (weapon && FlxMath.chanceRoll(5) && (!fireTime || fireTime.hasExpired)) {
						fireTime = new FlxDelay(3000 + int(Math.random() * 5000));
						fireTime.start();
					}
					if (fireTime && fireTime.hasExpired)
						weapon.fireAtPosition(Registry.player.x, Registry.player.y);
					
					//charging to the player
					if(_canCharge){
						if (FlxMath.chanceRoll(5) && !chargeDelay) { 
							// in the future : I'll add in Abilities Class
							// var attack:Abilities = new Abilities(this, 'charge');

							chargeDelay = new FlxDelay(5000 + int(Math.random() * 5000)); chargeDelay.start(); 
						}
						if (chargeDelay && chargeDelay.hasExpired) { charge(true); }
						if (_charging) {
							if (infos.anims.charge) play("charge");
							if( Math.abs(velocity.x) <= infos.gamePlay.speed)
								charge(false);
						} else if(velocity.x == 0 || isTouching(WALL))
							turnAround();
					}
										
					if (_tracking) {
						// stupidly go to the player and flee avoiding melee
						if (getPlayerDistance() > 210) {
							if (Registry.player.x < x) velocity.x = -infos.gamePlay.speed;
							else velocity.x = infos.gamePlay.speed;
						} else if (getPlayerDistance() < 190 && Registry.player.x != x) velocity.x = -getPlayerPosition() * infos.gamePlay.speed;
						else velocity.x = 0;
						facing = (getPlayerPosition() > 0) ? RIGHT : LEFT;
					} 
					if (_stayOnPlatform) {
						//avoid falling from platform
						var overX:Number = (facing == LEFT) ? x - width : x + width;
						if (!overlapsAt(overX, y + 1, Registry.solidTilesPool) || isTouching(WALL))
							turnAround();
					} 
					
					if (velocity.x != 0 && !_charging && infos.anims.walk ) play('walk');
					else if (velocity.x == 0 && infos.anims.idle) play('idle');
					
				} // end touching floor
			}//end onscreen
		}
		
		
		//begin to run
		protected function charge(value:Boolean=true):void {
			_charging = value;
			if (!_charging) {
				velocity.x = (facing == RIGHT) ? infos.gamePlay.speed : -infos.gamePlay.speed;
				Registry.fx.removeBlur();
			} else {
				chargeDelay = null;
				drag.x = 150;
				// Registry.fx.addBlur(this);
				if(infos.sounds.charge) infos.sounds.charge.play();
				facing = (getPlayerPosition() > 0) ? RIGHT : LEFT;
				velocity.x = getPlayerPosition() * infos.gamePlay.speed * 4;
			}
		}
		
		
		// make a u-turn
		protected function turnAround():void {
			if (facing == RIGHT) {
				facing = LEFT;
				velocity.x = -infos.gamePlay.speed;
			} else {
				facing = RIGHT;
				velocity.x = infos.gamePlay.speed;
			}
		}
		
		
		protected function getPlayerDistance():Number {
			return FlxU.getDistance(Registry.player.getMidpoint(), getMidpoint());
		}
		
		
		protected function getPlayerPosition():int {
			if (Registry.player.x > this.x)
				return 1;
			return -1;
		}
		
		override public function kill():void {
			if (infos.sounds.die) infos.sounds.die.play();
			_isDying = true;
			angle = 180;
			if (infos.gamePlay.points)
				Registry.player.score += infos.gamePlay.points;
			infos.gamePlay.points = 0;
			
			TweenMax.to(this, 1.5, {bezier: [{x: (this.x + 50), y: this.y - 100}, {x: this.x + 100, y: this.y}], onComplete: superKill});
		}
		
		
		private function superKill():void {
			Registry.enemyPool.remove(this,true);
			angle = 0;
			_isDying = false;
			
			super.kill()
		}
	}
}
